import ejs from 'ejs';
import path from 'path';
import colors from './colors';

/**
 * 渲染页面装饰器
 * @param view 页面路径
 * @param engine 引擎，默认ejs
 * @param options 引擎参数
 * @returns 
 */
export function RenderView(view: string, engine = ejs.renderFile, options = {}) {
  return function(target: any, _: string, descriptor: PropertyDescriptor) {
    const oldValue = descriptor.value;
    descriptor.value = (req: any, res: any, next: Function, params: any)=>{
      const model = oldValue.apply(target, [req, res, next, params]);
      // 返回页面
      engine(path.resolve('views',view), model.getData(), options, (err, data)=> {
        if(err) next();
        else {
            // 渲染页面
            console.info(colors.green, '[similar-server][VIEW]['+req.method.toUpperCase()+']['+new Date().toLocaleString()+']['+req.url+']');
            res.write(data);
            res.end();
        }
      });
    }
    return descriptor;
  }
}

/**
 * 请求返回装饰器
 * @returns 
 */
export function RenderAPI() {
  return function(target: any, _: string, descriptor: PropertyDescriptor) {
    const oldValue = descriptor.value;
    descriptor.value = (req: any, res: any, next: Function, params: any)=>{
      const promise = oldValue.apply(target, [req, res, next, params]);
      const send = (data: any)=>{
          // 返回页面
          console.info(colors.green, '[similar-server][API]['+req.method.toUpperCase()+']['+new Date().toLocaleString()+']['+req.url+']');
          res.setHeader('Content-Type', 'application/json');
          res.write(JSON.stringify(data));
          res.end();
      }
      if(promise instanceof global.Promise) {
        promise.then(model=>{
          send(model.getData());
        })
      } else {
        send(promise.getData());
      }
    }
    return descriptor;
  }
}

/**
 * 请求装饰器
 * @param path 请求路径
 * @param method 请求方法
 * @returns 
 */
export function Method(path: string, method: string) {
  return function(target: any, operationId: string, descriptor: PropertyDescriptor) {
    const oldValue = descriptor.value;
    descriptor.value = (req: any, res: any, next: Function, params: any)=>{
      if(req.method.toUpperCase() !== method.toUpperCase()) {
        next();
        return;
      }
      oldValue.apply(target, [req, res, next, params]);
    }

    target.Routes = target.Routes || [];
    target.Routes.push({ operationId, path, children: [descriptor.value], type: 'route', plugins: [] });

    return descriptor;
  }
} 

/**
 * POST方法装饰器
 * @param path 请求路径
 * @returns 
 */
export function Post(path: string) {
  return Method(path, 'post')
}

/**
 * GET方法装饰器
 * @param path 请求路径
 * @returns
 */
export function Get(path: string) {
  return Method(path, 'get')
}

/**
 * PUT方法装饰器
 * @param path 请求路径
 * @returns 
 */
export function Put(path: string) {
  return Method(path, 'put')
}

/**
 * DELETE方法装饰器
 * @param path 请求路径
 * @returns
 */
export function Delete(path: string) {
  return Method(path, 'delete')
}
